\begin{section}{Desarrollo}
	Lo primero que hicimos fue una implementación preliminar de la serie de Gregory, la fórmula de Machin y de la serie de Ramanujan con tipos de datos genéricos ({\em templates}) para después no necesitar reimplementar los algoritmos a la hora de implementar la aritmética de $t$ dígitos. En todos los algoritmos buscamos hacer tantas operaciones como fue posible usando enteros para evitar la mayor cantidad de errores de precisión que podían surgir en los métodos. En todos los casos donde hubo operaciones en enteros, se utilizó el tipo \code{unsigned long long int} para tener un rango de números de 64 bits y disminuir la probabilidad de {\em overflow}. Las primeras pruebas de los algoritmos fueron hechas usando los tipos \code{float} y \code{double}.

\begin{subsection}{Serie de Gregory}
	Al implementar la serie de Gregory, en cada término $G_i$ de la serie, calculamos $2i+1$ en enteros ya que asumimos que el algoritmo nunca se va a ejecutar con una cantidad de iteraciones tal que desborde. Luego de hacer el cálculo, el resultado se convierte a \code{Real} y calculamos su recíproco multiplicado por 4. Esto se suma o se resta al resultado acumulado de la serie hasta el término $i-1$ según si es un término par (suma) o impar (resta).
\end{subsection}

\begin{subsection}{Fórmula de Machin}
	La Fórmula de Machin la implementamos como el despeje de la fórmula presentada 
		$$ \pi = 16 \arctan\left(\frac{1}{5}\right) + 4 \arctan\left(\frac{1}{239}\right)$$
	La implementación del arcotangente fue muy similar a la implementación de la serie de Gregory. La diferencia está en el cálculo de $x^{2i+1}$, siendo $x$ el parámetro del arcotangente a calcular. Este cálculo lo hacemos mediante la función \code{pow} de la biblioteca standard de matemática de \code{C}, que devuelve el resultado de la cuenta en \code{double} para ser luego convertido a \code{Real} y después calcular la división correspondiente.
\end{subsection}

\begin{subsection}{Serie de Ramanujan}
	La serie de Ramanujan requiere realizar operaciones de potencia y factorial, las cuales crecen lo suficientemente rápido como para desbordar un entero de 64 bits en las primeras iteraciones. Por este motivo, realizamos todas las cuentas de factoriales y potencia en punto flotante. Aprovechando propiedades de la potencia y el factorial, evitamos recalcular en cada término gran parte las cuentas mediante variables que guardan el valor de cada cuenta en el término anterior. Por motivos de simplicidad de código y para obtener más precisión en las cuentas intermedias, el primer término fue extraído de la serie y se suma luego de terminar el cálculo. Luego de obtener el resultado completo de la serie, se multiplica el resultado por $\sqrt{8}$ (usando la implementación de la biblioteca standard de matemática de \code{C}) y se lo divide por 9801. Para finalizar el cálculo, se calcula el recíproco del resultado parcial.
\end{subsection}

\begin{subsection}{Aritmética de $t$ dígitos}
	Para poder trabajar con aritmética de $t$ dígitos, se implementó el tipo de dato \code{Real} donde se puede trabajar con hasta 52 dígitos binarios de precisión en la mantisa. Para aproximar los números a $t$ dígitos implementamos los métodos de aproximación por truncamiento y redondeo\footnote{Sección 1.2 del libro {\em Análisis Numérico} \cite{burden}}. También definimos todas las operaciones aritméticas en $t$ dígitos necesarias para que puedan ejecutarse los algoritmos sin hacer ninguna modificación a las implementaciones previamente hechas.

	\begin{subsubsection}{Truncamiento}
		Para truncar copiamos el \code{double} con el número original y mediante una máscara ponemos en 0 los $52-t$ bits menos significativos del número. Luego se guarda en la estructura el \code{double} con $t$ bits significativos en la mantisa.
	\end{subsubsection}

	\begin{subsubsection}{Redondeo}
		Para obtener un número redondeado dado el número original, le sumamos un 1 en el bit $t+1$ de la mantisa y luego lo truncamos a $t$ bits. Para calcular el número que es necesario sumarle, nos basamos en la representación de números de punto flotante. Al saber que los números de punto flotante son de la forma $2^e \times (1+\bin{0.d_1 d_2 \ldots d_{52}})$ donde $d_i$ es el dígito binario $i$ de la mantisa del número, buscamos conseguir el número tal que $d_{t+1} = 1$ y el resto de los dígitos es $0$ mediante operaciones lógicas. Este número formado es exactamente $2^e \times (1+2^{-(t+1)})$. Si sumamos este nuevo número al número original, quedaría 
		\begin{align*}
			n &= 2^e \times (1+\bin{0.d_1 d_2 \ldots d_{52}}) + 2^e \times (1+2^{-(t+1)}) \\
			  &= 2^e \times (1+\bin{0.d_1 d_2 \ldots d_{52}}+2^{-(t+1)})+2^e
		\end{align*}
Luego restamos el $2^e$ restante a $n$ y faltaría únicamente truncar a $t$ dígitos para obtener el número redondeado final.
	\end{subsubsection}

\end{subsection}

\begin{subsection}{Pruebas}

	Una vez implementados los algoritmos, se comenzó con las pruebas. Comenzamos por ver cómo se comportaban los algorimos con un máximo de precisión posible en el tipo \code{Real} (52 bits en la mantisa) calculando con tres iteraciones y más adelante con hasta 20 iteraciones. Luego fijamos la cantidad de operaciones y calculamos el error relativo de los tres algoritmos variando la cantidad de dígitos.

	Continuamos las pruebas comparando la precisión de nuestro método de redondeo con el de truncamiento. Para esto fijamos para cada algoritmo un número de iteraciones y variamos la precisión de 0 a 51 dígitos.
	
	%esperando corroborar nuestras primeras conjeturas de que no afectaría tanto a la Serie de Gregory ni a la Formula de Machin ya que los primeros resultados nos mostraban que la Serie de Ramanujan donde cada termino agregaba exactamente 8 dígitos a la aproximación de pi. \\

%, esperando corroborar nuestra suposición de que la precisión del redondeo era siempre mayor o igual que la del truncamiento en la Serie de Ramanujan, ya que al aproximarse por abajo hacia Pi, siempre agregaría precisión, no así en Gregory o Machín, que el $-1^n$ hace que el valor oscile por arriba y por abajo a pi en cada iteración. 

\end{subsection}
\end{section}

